package model.code.line;

import event.TextReplacementEvent;
import model.Segment;
import model.code.CodeFileChunk;
import model.code.Constants;
import model.code.Document;
import model.code.Section;
import model.symbol.Scope;
import model.symbol.Symbol;
import util.StringUtil;

/**
 * This is a {@link Line} specifically for names of {@link Symbol}s.
 * @author Neil Dickson
 */
public class NameLine extends SingleLine {
	private final Symbol	symbol;

	/**
	 * This is the set of characters (other than alphanumeric characters) allowed for most named {@link Symbol}s.
	 * NOTE: It's only underscore now, since C/C++ don't support '?', '@', or '$' in names, and they aren't critical for assembly.  If support for Perl is ever needed, just put '$', '@', or '%' as the type instead.
	 */
	private static final char[]	WORD_EXTRA_CHARS = {'_'};
	/**
	 * Characters allowed in names of {@link Constants}, {@link Section}s, and {@link Document}.
	 * NOTE: Don't have both '*' and '/' in here, because then users could end the block comment in C/C++, ruining the file.  I've omitted '*' because I use it in the doc comment border.
	 */
	private static final char[]	FULL_EXTRA_CHARS = {'_','$','@','?',' ','.','&','/',';'};

	public NameLine(char[] text,Symbol symbol) {
		super(text,(symbol instanceof CodeFileChunk) ? (CodeFileChunk)symbol : null,(symbol instanceof CodeFileChunk) ? CodeFileChunk.LOCATION_NAME : CodeFileChunk.LOCATION_NOWHERE);
		this.symbol = symbol;
		addReference(symbol,0,true);
		trimToSize();
	}

	public NameLine(char[] text,CodeFileChunk parent, int locationType, int locationIndex, Symbol symbol) {
		super(text,parent,locationType,locationIndex);
		this.symbol = symbol;
		addReference(symbol,0,true);
		trimToSize();
	}

	public TextReplacementEvent replace(LineObserver culprit,int startCol, int endCol, char[] newText) {
		char[] adjusted = StringUtil.reduceToWord(newText,(symbol instanceof Constants || symbol instanceof Section || symbol instanceof Document || symbol instanceof Segment) ? FULL_EXTRA_CHARS : WORD_EXTRA_CHARS);
		TextReplacementEvent event = super.replace(culprit,startCol,endCol,adjusted);
		event.addReferences(Scope.getAddedRenameReferences(symbol));
		return event;
	}
}
